/* strerror_tls.c

   An implementation of strerror() that is made thread-safe through
   the use of thread-local storage.

   See also strerror_tsd.c.

   Thread-local storage requires: Linux 2.6 or later, NPTL, and
   gcc 3.3 or later.
*/
#define _GNU_SOURCE /* Get '_sys_nerr' and '_sys_errlist' \
                       declarations from <stdio.h> */
#include <pthread.h>
#include <stdio.h>
#include <string.h> /* Get declaration of strerror() */

/* Maximum length of string in per-thread buffer returned by strerror() */
#define MAX_ERROR_LEN 256

/* Thread-local return buffer */
static __thread char buf[MAX_ERROR_LEN];

char* strerror(int err) {
  if (err < 0 || err >= _sys_nerr || _sys_errlist[err] == NULL) {
    snprintf(buf, MAX_ERROR_LEN, "Unknown error %d", err);
  } else {
    strncpy(buf, _sys_errlist[err], MAX_ERROR_LEN - 1);
    buf[MAX_ERROR_LEN - 1] = '\0'; /* Ensure null termination */
  }

  return buf;
}